package xiao_jin.fantastic_journey.generator;

import com.google.common.collect.ImmutableList;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.minecraft.data.server.recipe.RecipeExporter;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.data.server.recipe.SmithingTransformRecipeJsonBuilder;
import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.Items;
import net.minecraft.recipe.Ingredient;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.RegistryWrapper;
import xiao_jin.fantastic_journey.core.init.ModBlocks;
import xiao_jin.fantastic_journey.core.init.ModItems;
import xiao_jin.fantastic_journey.util.ModUtil;

import java.util.concurrent.CompletableFuture;

public final class ModRecipesProvider extends FabricRecipeProvider {
    public ModRecipesProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
        super(output, registriesFuture);
    }

    private static final ImmutableList<ItemConvertible> relicIronOre = ImmutableList.of(ModBlocks.RELICTECH_IRON_ORE, ModBlocks.DEEP_RELICTECH_IRON_ORE);
    private static final ImmutableList<ItemConvertible> relicCopperOre = ImmutableList.of(ModBlocks.RELICTECH_COPPER_ORE, ModBlocks.DEEP_RELICTECH_COPPER_ORE);
    private static final ImmutableList<ItemConvertible> relicDiamondOre = ImmutableList.of(ModBlocks.RELICTECH_DIAMOND_ORE, ModBlocks.DEEP_RELICTECH_DIAMOND_ORE);
    private static final ImmutableList<ItemConvertible> relicGoldOre = ImmutableList.of(ModBlocks.RELICTECH_GOLD_ORE, ModBlocks.DEEP_RELICTECH_GOLD_ORE);
    private static final ImmutableList<ItemConvertible> relicLapisOre = ImmutableList.of(ModBlocks.RELICTECH_LAPIS_ORE, ModBlocks.DEEP_RELICTECH_LAPIS_ORE);
    private static final ImmutableList<ItemConvertible> relicRedstoneOre = ImmutableList.of(ModBlocks.RELICTECH_REDSTONE_ORE, ModBlocks.DEEP_RELICTECH_REDSTONE_ORE);
    private static final ImmutableList<ItemConvertible> relicEmeraldOre = ImmutableList.of(ModBlocks.RELICTECH_EMERALD_ORE, ModBlocks.DEEP_RELICTECH_EMERALD_ORE);

    @Override
    public void generate(RecipeExporter exporter) {
        offerShapelessRecipe(exporter, ModItems.EXPLOSIVE_STEEL_INGOT, ModBlocks.EXPLOSIVE_STEEL_BLOCK, "explosive_steel_ingot", 9);
        offerShapelessRecipe(exporter, ModItems.EXPLOSIVE_STEEL_PARTICLE, ModItems.EXPLOSIVE_STEEL_INGOT, "explosive_steel_particle", 9);
        ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, ModItems.EXPLOSIVE_STEEL_INGOT)
                .pattern("###").pattern("###").pattern("###")
                .input('#', ModItems.EXPLOSIVE_STEEL_PARTICLE)
                .criterion(hasItem(ModItems.EXPLOSIVE_STEEL_PARTICLE), conditionsFromItem(ModItems.EXPLOSIVE_STEEL_PARTICLE))
                .offerTo(exporter, ModUtil.getIdOfMod("explosive_steel_ingot2"));
        ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, ModItems.EXPLOSIVE_STEEL_INGOT)
                .pattern("###").pattern("#A#").pattern("###")
                .input('#', ModItems.EXPLOSIVE_STEEL_PIECE).input('A', Items.IRON_INGOT).criterion(hasItem(ModItems.EXPLOSIVE_STEEL_PIECE), conditionsFromItem(ModItems.EXPLOSIVE_STEEL_PIECE))
                .offerTo(exporter, ModUtil.getIdOfMod("explosive_steel_ingot3"));
        ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, ModBlocks.EXPLOSIVE_STEEL_BLOCK)
                .pattern("###").pattern("###").pattern("###")
                .input('#', ModItems.EXPLOSIVE_STEEL_INGOT)
                .criterion(hasItem(ModItems.EXPLOSIVE_STEEL_INGOT), conditionsFromItem(ModItems.EXPLOSIVE_STEEL_INGOT))
                .offerTo(exporter, ModUtil.getIdOfMod("explosive_steel_block"));
        ShapedRecipeJsonBuilder.create(RecipeCategory.FOOD, ModItems.ANCIENT_CHOCOLATE)
                .pattern("#A#").pattern("CBC").pattern("#A#")
                .input('#', Items.ANCIENT_DEBRIS).input('A', Items.NETHERITE_INGOT).input('B', Items.CAKE).input('C', Items.SUGAR)
                .criterion(hasItem(ModItems.EXPLOSIVE_STEEL_INGOT), conditionsFromItem(ModItems.EXPLOSIVE_STEEL_INGOT))
                .offerTo(exporter, ModUtil.getIdOfMod("ancient_debris_chocolate"));
        offerCustomizedForgingFormulaUpgrade(exporter, ModItems.ANCIENT_RECIPES, ModItems.ANCIENT_CHOCOLATE, ModItems.WARDEN_HEART, RecipeCategory.FOOD, ModItems.NSCULK_CHOCOLATE, "ancient_chocolate_upgrade");
        offerCustomizedSmithingTemplateCopyingRecipe(exporter, ModItems.ANCIENT_RECIPES, Ingredient.ofItems(Items.WRITABLE_BOOK), Items.SCULK_VEIN, 2);
        offerSmelting(exporter, relicIronOre, RecipeCategory.MISC, Items.IRON_INGOT, 0.7f, 200, "relic_iron_ore");
        offerSmelting(exporter, relicCopperOre, RecipeCategory.MISC, Items.COPPER_INGOT, 0.7f, 200, "relic_copper_ore");
        offerSmelting(exporter, relicDiamondOre, RecipeCategory.MISC, Items.DIAMOND, 1.0f, 200, "relic_diamond_ore");
        offerSmelting(exporter, relicGoldOre, RecipeCategory.MISC, Items.GOLD_INGOT, 1.0f, 200, "relic_gold_ore");
        offerSmelting(exporter, relicLapisOre, RecipeCategory.MISC, Items.LAPIS_BLOCK, 0.2f, 200, "relic_lapis_ore");
        offerSmelting(exporter, relicRedstoneOre, RecipeCategory.MISC, Items.REDSTONE, 0.7f, 1, "relic_redstone_ore");
        offerSmelting(exporter, relicEmeraldOre, RecipeCategory.MISC, Items.EMERALD, 1.0f, 200, "relic_emerald_ore");
        offerBlasting(exporter, relicIronOre, RecipeCategory.MISC, Items.IRON_INGOT, 0.7f, 100, "relic_iron_ore");
        offerBlasting(exporter, relicCopperOre, RecipeCategory.MISC, Items.COPPER_INGOT, 0.7f, 100, "relic_copper_ore");
        offerBlasting(exporter, relicDiamondOre, RecipeCategory.MISC, Items.DIAMOND, 1.0f, 100, "relic_diamond_ore");
        offerBlasting(exporter, relicGoldOre, RecipeCategory.MISC, Items.GOLD_INGOT, 1.0f, 100, "relic_gold_ore");
        offerBlasting(exporter, relicLapisOre, RecipeCategory.MISC, Items.LAPIS_BLOCK, 0.2f, 100, "relic_lapis_ore");
        offerBlasting(exporter, relicRedstoneOre, RecipeCategory.MISC, Items.REDSTONE, 0.7f, 100, "relic_redstone_ore");
        offerBlasting(exporter, relicEmeraldOre, RecipeCategory.MISC, Items.EMERALD, 1.0f, 100, "relic_emerald_ore");
    }

    /**
     * 自定义锻造升级配方
     *
     * @param category 配方类别
     * @param template 模板物品
     * @param base     基地物品
     * @param addition 材料物品
     * @param result   结果物品
     */
    public static void offerCustomizedForgingFormulaUpgrade(RecipeExporter exporter, Item template, Item base, Item addition, RecipeCategory category, Item result, String recipeId) {
        SmithingTransformRecipeJsonBuilder.create(
                        Ingredient.ofItems(template), Ingredient.ofItems(base), Ingredient.ofItems(addition), category, result)
                .criterion("ancient_recipes", conditionsFromItem(template))
                .offerTo(exporter, ModUtil.getIdOfMod(recipeId));
    }

    /**
     * 自定义模版复制
     *
     * @param consumables 消耗物
     * @param resource    基底物品
     * @param template    模板和输出物品
     * @param number      输出物品数量
     */
    public static void offerCustomizedSmithingTemplateCopyingRecipe(RecipeExporter exporter, ItemConvertible template, Ingredient resource, ItemConvertible consumables, int number) {
        ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, template, number)
                .input('#', consumables)
                .input('C', resource)
                .input('S', template)
                .pattern("#S#")
                .pattern("#C#")
                .pattern("###")
                .criterion(hasItem(template), conditionsFromItem(template))
                .offerTo(exporter);
    }
}